﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Okazuki.MVVM.PrismSupport.ViewModels;
using System.ComponentModel.DataAnnotations;

namespace Okazuki.MVVM.PrismSupport.Test.ViewModels
{
    [TestClass]
    public class ValidatableViewModelTest
    {
        class TestTargetViewModel : ValidatableViewModelBase
        {
            private string input;

            [Required(ErrorMessage = "Error")]
            public string Input
            {
                get
                {
                    return this.input;
                }

                set
                {
                    this.input = value;
                    this.RaisePropertyChanged(() => Input);
                }
            }

            [Required(ErrorMessage = "Error2")]
            public string Input2 { get; set; }
        }

        private TestTargetViewModel target;

        [TestInitialize]
        public void SetUp()
        {
            this.target = new TestTargetViewModel();
        }

        [TestCleanup]
        public void TearDown()
        {
            this.target = null;
        }

        [TestMethod]
        public void TestValidateInput()
        {
            Assert.IsFalse(this.target.HasErrors, "初期状態ではエラーはない");

            this.target.Input = null;
            Assert.IsTrue(this.target.HasErrors, "エラーになっているはず");
            Assert.AreEqual("Error", this.target["Input"], "エラーメッセージの確認");
        }

        [TestMethod]
        public void TestValidateProperty()
        {
            Assert.IsFalse(this.target.HasErrors, "初期状態ではエラーはない");
            this.target.ValidateProperty("Input2");
            Assert.IsTrue(this.target.HasErrors, "Input2はnullなのでエラーになってるはず");
            Assert.AreEqual("Error2", this.target["Input2"], "エラーメッセージの確認");
        }

        [TestMethod]
        public void TestValidateProperties()
        {
            Assert.IsFalse(this.target.HasErrors, "初期状態ではエラーはない");
            this.target.ValidateProperties();
            Assert.IsTrue(this.target.HasErrors, "エラーになってるはず");
            Assert.AreEqual("Error", this.target["Input"], "エラーメッセージの確認");
            Assert.AreEqual("Error2", this.target["Input2"], "エラーメッセージの確認");

            Assert.AreEqual(2, this.target.ValidationErrors.Count(), "エラー件数は２");
            Assert.AreEqual(
                "Input",
                this.target.ValidationErrors.ElementAt(0).PropertyName,
                "プロパティ名の確認");
            Assert.AreEqual(
                "Input2",
                this.target.ValidationErrors.ElementAt(1).PropertyName,
                "プロパティ名の確認");
        }
    }
}
